#copyright samphippen
#licensed under the gplv3
import sys, pygame
from random import randint
from time import sleep
from math import sin,cos,tan,asin,acos,atan,atan2,floor

def wasd():
	w = pygame.key.get_pressed()[pygame.K_w]
	a = pygame.key.get_pressed()[pygame.K_a]
	s = pygame.key.get_pressed()[pygame.K_s]
	d = pygame.key.get_pressed()[pygame.K_d]
	horiz = d-a
	vert = s-w
	return [horiz,vert]
def click():
	mouseloc = pygame.mouse.get_pos()	
def if_b_is_dow():
	global bounce
	b = pygame.key.get_pressed()[pygame.K_b]
	if b == 1:
		bounce = 1-bounce
		
def if_m_is_down():
	global go
	m = pygame.key.get_pressed()[pygame.K_m]		
	if m == 1:
		go = 1-go
	
def applyforce(force_vector):
	global speed
	global ballmass	
	a = [force_vector[0]/ballmass,force_vector[1]/ballmass]
	if abs(speed[0]+a[0]) < speedcap[0]:
		speed[0] += a[0]
	elif abs(speed[0]+a[0]) < speedcap[0]:
		speed[0] = speedcap[0]	
	if abs(speed[1]+a[1]) < speedcap[1]:
		speed[1] += a[1]
	elif abs(speed[1]+a[1]) < speedcap[1]:
		speed[1] = speedcap[1]	
	return 0
def gravitational_force(point,mass):
	global speed
	global ballmass
	global ballrect
	G = 4
	deltax = point[0] - (ballrect.left+10)
	deltay = point[1] - (ballrect.top+10)
	try:
		force_g = (G*ballmass*mass)/((deltax**2+deltay**2)**0.5)
	except:
		force_g = 0	
	theta = atan2(deltay,deltax)
	y = force_g*sin(theta)
	x = force_g*cos(theta)			
	g_vector=[x,y]
	return g_vector


go = 0
bounce = 0
pygame.init()
#dragonforce = pygame.mixer.Sound("ff.ogg")
#dragonforce.set_volume(1.0)
#dragonforce.play()
size = width, height = 800, 600
speed = [0, 0]
black = 0, 0, 0
screen = pygame.display.set_mode(size)
screensurface = pygame.Surface([width,height])
screensurface.fill([255,255,255])
screensurface.set_colorkey([255,255,255])
lines = []
screenrect = screensurface.get_rect()
screenrect.center = [width/2,height/2]
ball = pygame.Surface([3,3])
ball.fill([40,255,10])
ballmass = 3
speedcap = [10,10]
bouncearray = []
for i in range(0,randint(25,100)):
	size = 20
	ball2 = pygame.Surface([size,size])
	pygame.draw.circle(ball2,(randint(0,255),
	randint(0,255),randint(0,255)),
	(size/2,size/2),size/2)
	ball2rect = ball2.get_rect()
	ball2rect.left = randint(0,width)
	ball2rect.top = randint(0,height)
	gravmass = size**2/100
	bouncearray.append([ball2,ball2rect,gravmass])

ballrect = ball.get_rect()
pixelarray = []

while 1:
	e = wasd()
	if abs(speed[0]+e[0]) < speedcap[0]:
		speed[0] += e[0]
	if abs(speed[1]+e[1]) < speedcap[1]:
		speed[1] += e[1]			
	for event in pygame.event.get():
		if event.type == pygame.QUIT: sys.exit()
		if event.type == pygame.MOUSEBUTTONDOWN:
			gravity_vector = gravitational_force(pygame.mouse.get_pos(),1000)
			applyforce(gravity_vector)
	if_b_is_dow()
	
	for i in bouncearray:
		if ballrect.colliderect(i[1]) and bounce == 1:
			speed[0] = -1*speed[0]
			speed[1] = -1*speed[1]	
	
	colour = (randint(0,255),randint(0,255),randint(0,255))
	for i in bouncearray:
		i[0].set_colorkey((0,0,0))
		gravity_vector = gravitational_force([i[1].center[0],i[1].center[1]],i[2])
		applyforce(gravity_vector)
		
	if_m_is_down()
	if go:
		gravity_vector = gravitational_force(pygame.mouse.get_pos(),100)	
		applyforce(gravity_vector)
	if ballrect.left < 0:
		speed[0] = speed[0]*-1
	if ballrect.right > width:
		speed[0] = speed[0]*-1
	if ballrect.top < 0:
		speed[1] = speed[1]*-1
	if ballrect.bottom > height:
		speed[1] = speed[1]*-1
	ballrect = ballrect.move(speed)
	#draw functions
	screen.fill(black)
	ball.fill((randint(0,255),randint(0,255),randint(0,255)))
	screen.blit(ball, ballrect)
	pixel = pygame.Surface([1,1])
	pixelrect = pixel.get_rect()
	pixel.fill([randint(0,255),randint(0,255),randint(0,255)])
	pixelrect.center = ballrect.center
	if len(pixelarray) > 0:
		previouscenter = pixelarray[len(pixelarray)-1][1].center
		pygame.draw.line(screensurface,(randint(0,255),randint(0,255),randint(0,255)),
		pixelrect.center,previouscenter)
		screenrect = screensurface.get_rect()
		screen.blit(screensurface,screenrect)
		lines.append([pixelrect.center,previouscenter])
	if len(lines) >= 50:
		firstline = lines[0]
		pygame.draw.line(screensurface,(255,255,255),
		firstline[0],firstline[1])	
		lines.pop(0)
	pixelarray.append([pixel,pixelrect])
	if len(pixelarray) >= 200:
		pixelarray.pop(0)
	
	for i in pixelarray:
		screen.blit(i[0],i[1])	
	for i in bouncearray:
		screen.blit(i[0],i[1])	
	pygame.display.flip()
	sleep(0.02)
	
